/* 使用 canvas 压缩图片，尺寸压缩 + 质量压缩
 * 尺寸压缩：设定宽度、高度上限，超过则按照图片原始宽高比缩小
 * 质量压缩：在 Canvas 中通过设置质量压缩比率减小图片文件的大小
 *
 * 最简使用方法：
 * 包含本文件后调用方法 bindCompressCtl()，传入上传控件的 id
 * 然后 imageOri 表示原始图片，imageCompressed表示压缩后的图片
 * imageOri 不是 base64 图片，imageCompressed 是 base64 图片，上传时直接传入该变量即可。
 *
 * 高级使用：
 * MAX_WIDTH 尺寸压缩的最大宽度，原始图片的宽度如果大于该值则 sizeRatio = 原始宽度 / MAX_WIDTH
 *           以该系数再计算高度的缩小后的长度 = image.naturalHeight / sizeRatio
 * MAX_HEIGHT 尺寸压缩的最大高度，原始图片的高度如果大于该值则 sizeRatio = 原始高度 / MAX_HEIGHT
 * ACCEPT 表示接受的图片文件的类型
 * MAX_SIZE 选择文件的最大大小，默认3MB
 */
let uploadCtl = null;
let imageOri = null;// 原始图片
let imageCompressed = null;// 压缩后的图片,base64Image 直接赋值给 image.src
let sizeRatio = 1;// 尺寸压缩比率，以后检测=1表示不需要压缩
let MAX_WIDTH = 1024;// 尺寸压缩的宽度最大值
let MAX_HEIGHT = 768;// 尺寸压缩的高度最大值
let g_base64Image = null;

const ACCEPT = '["image/jpg","image/jpeg","image/png"]';// 允许上传的图片格式
const MAX_SIZE = 3 * 1024 * 1024;
const MAX_SIZE_STR = '3MB';
const displayImage = 'block';// 要隐藏的修改为 none，要显示修改为 block
const compressRatio = 0.8;// 质量压缩比率，越小失真越严重，可以使用0.5，这里使用0.1为了能明显看出效果



function checkFileSize(){// 检查文件大小是否超过
	const size = imageOri.size;
	if( size > MAX_SIZE )
		return false;
	else
		return true;
}

function checkFileType(){// 检测图片的文件类型
	const fileType = imageOri.type;
	if( ACCEPT.includes(fileType) )
		return true;
	else
		return false;
}

function compress(base64Image){
	const image = new Image();
	image.addEventListener('load',function(e){
		if( image.naturalWidth > MAX_WIDTH ){
			sizeRatio = image.naturalWidth / MAX_WIDTH;
			MAX_HEIGHT = image.naturalHeight / sizeRatio;
		}
		
		if( image.naturalHeight > MAX_HEIGHT ){
			sizeRatio = image.naturalHeight / MAX_HEIGHT;
			MAX_WIDTH = image.naturalWidth / sizeRatio;
		}
		
		if( sizeRatio == 1 ){// 宽高都没有超标，则在尺寸上不压缩尺寸
			MAX_WIDTH = image.naturalWidth;
			MAX_HEIGHT = image.naturalHeight;
		}
		
		const canvas = document.createElement('canvas');
		canvas.setAttribute('id','__compress__');
		canvas.width = MAX_WIDTH;
		canvas.height = MAX_HEIGHT;
		canvas.style.visibility = 'visible';
				
		
		const ctx = canvas.getContext('2d');
		ctx.clearRect(0,0,MAX_WIDTH,MAX_HEIGHT);
		ctx.drawImage(image,0,0,MAX_WIDTH,MAX_HEIGHT);
		
		imageCompressed = canvas.toDataURL('image/jpeg',compressRatio);
		//console.log('压缩后的图片：');
		//console.log(imageCompressed);
		
		// 显示压缩后的图片
		const img = new Image();
		img.src = imageCompressed;
		img.style.display = displayImage;
		document.body.appendChild(img);
		
		canvas.remove();
	})
	
	// 显示原始图片
	
	image.src = base64Image;
	// image.style.visibility = 'hidden'; 占位隐藏
	image.style.display = displayImage;// 不占位隐藏
	document.body.appendChild(image);
	
	
}

function convertImage2Base64(imageFile,callback){// 将图片文件转换为 base64 文件并进行处理
	let reader = new FileReader();
	reader.addEventListener('load',function(e){
		const base64Image = e.target.result;// 转换为 base64文件
		
		//console.log('原始图片：');
		//console.log(base64Image);
		
		g_base64Image = e.target.result;
		callback && callback(base64Image);// 处理 base64文件
		reader = null;
	})
	
	reader.readAsDataURL(imageFile);// 读取图片文件，触发上面的绑定时间，转换文件
}

// 初始化
// 获取上传用 input 控件，原始图片
function bindCompressCtl(uploadCtlId){
	uploadCtl = document.getElementById(uploadCtlId);
	if( !uploadCtl ){
		alert('没有获取到用于上传文件的控件！');
		return;
	}
	
	uploadCtl.addEventListener('change',function(e){// 绑定监听事件
		const [file]=e.target.files;// 获取文件数组的第一个元素
		if(!file){// 检测是否接受到图片文件
			alert('没有获取到图片文件！');
			return;
		}
		
		imageOri = file;
		
		if(!checkFileType()) {
			alert('不支持的文件类型！');
			return;
		}
		
		if(!checkFileSize()){// 不可上传过大的文件
			alert(`文件大小不可超过 ${MAX_SIZE_STR}`);
			return;
		}
		
		// 将图片文件转换为 base64 文件并进行处理
		convertImage2Base64(file,compress);
	})
}



